/**
 * @brief 控制外设电源
 */

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

#include "expower.h"

LOG_MODULE_REGISTER(expower, CONFIG_EXPOWER_LOG_LEVEL);

struct expwrctrl_data {
    uint8_t state;
};

struct expwrctrl_config {
    struct gpio_dt_spec port;
};

static int _set(const struct device *dev, int s)
{
    struct expwrctrl_data *p_data = dev->data;
    const struct expwrctrl_config *p_cfg = dev->config;

    p_data->state = s & 0x01;
    LOG_DBG("expower is %s", p_data->state ? "ON" : "OFF");
    return gpio_pin_set_dt(&p_cfg->port, p_data->state);
}

static int _get(const struct device *dev)
{
    struct expwrctrl_data *p_data = dev->data;
    return p_data->state;
}

static int init_fn(const struct device *dev)
{
    int err;
    const struct expwrctrl_config *p_cfg = dev->config;

    if (!device_is_ready(p_cfg->port.port)) {
        LOG_ERR("expower GPIO module is not ready.");
        return -ENODEV;
    }

    err = gpio_pin_configure_dt(&p_cfg->port, GPIO_OUTPUT_INACTIVE);
    if (err != 0) {
        LOG_ERR("Error %d: failed to config %s pin %d", err, p_cfg->port.port->name,
                p_cfg->port.pin);
        return err;
    }

    /* default state */
    _set(dev, 1);

    /* must set a delay until power is stable */
    k_msleep(5);
    return err;
}

static struct expwrctrl_data _data = {
    .state = 0,
};

static const struct expwrctrl_config _config = {
    .port = GPIO_DT_SPEC_GET(DT_NODELABEL(expwrctrl), gpios),
};

static const struct expwrctrl_driver_api _apis = {
    .get = _get,
    .set = _set,
};

// static expwrctrl_t _expwrctrl = {
//     .api = &_apis,
// };

// expwrctrl_t *expwrctrl_inst = &_expwrctrl;

DEVICE_DT_DEFINE(DT_NODELABEL(expwrctrl), init_fn, NULL, &_data, &_config, POST_KERNEL,
                 CONFIG_EXPOWER_INIT_PRIORITY, &_apis);
